/*
 * Copyright 2011 Katsunori Koyanagi
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package sweezy.swf.converter
{
	import flash.filters.BitmapFilterType;
	import flash.filters.BlurFilter;
	import flash.filters.ColorMatrixFilter;
	import flash.filters.ConvolutionFilter;
	import flash.filters.DropShadowFilter;
	import flash.filters.GlowFilter;
	import flash.filters.GradientBevelFilter;
	import flash.filters.GradientGlowFilter;
	import sweezy.swf.structure.BevelFilter;
	import sweezy.swf.structure.BlurFilter;
	import sweezy.swf.structure.ColorMatrixFilter;
	import sweezy.swf.structure.ConvolutionFilter;
	import sweezy.swf.structure.DropShadowFilter;
	import sweezy.swf.structure.GlowFilter;
	import sweezy.swf.structure.GradientBevelFilter;
	import sweezy.swf.structure.GradientGlowFilter;
	import sweezy.swf.structure.RGBA;

	public class FilterConverter
	{

		public static function bevelFilterNativeToStructure(filter:flash.filters.BevelFilter):sweezy.swf.structure.BevelFilter
		{
			var result:sweezy.swf.structure.BevelFilter = new sweezy.swf.structure.BevelFilter();
			result.angle = filter.angle;
			result.blurX = filter.blurX;
			result.blurY = filter.blurY;
			result.distance = filter.distance;
			result.highlightColor = ColorConverter.colorAndAlphaToRgba(filter.highlightColor, filter.highlightAlpha);
			result.innerShadow = filter.type === BitmapFilterType.FULL || filter.type === BitmapFilterType.INNER;
			result.knockout = filter.knockout;
			result.onTop = filter.type === BitmapFilterType.FULL || filter.type === BitmapFilterType.OUTER;
			result.passes = filter.quality;
			result.shadowColor = ColorConverter.colorAndAlphaToRgba(filter.shadowColor, filter.shadowAlpha);
			result.strength = filter.strength;

			return result;
		}

		public static function bevelFilterStructureToNative(filter:sweezy.swf.structure.BevelFilter):flash.filters.BevelFilter
		{
			var result:flash.filters.BevelFilter = new flash.filters.BevelFilter();
			result.angle = filter.angle;
			result.blurX = filter.blurX;
			result.blurY = filter.blurY;
			result.distance = filter.distance;
			result.highlightAlpha = filter.highlightColor.alpha / 255;
			result.highlightColor = ColorConverter.rgbToColor(filter.highlightColor);
			result.knockout = filter.knockout;
			result.quality = filter.passes;
			result.shadowAlpha = filter.shadowColor.alpha / 255;
			result.shadowColor = ColorConverter.rgbToColor(filter.shadowColor);
			result.strength = filter.strength;
			if (filter.innerShadow && filter.onTop)
			{
				result.type = BitmapFilterType.FULL;
			}
			else if (filter.innerShadow)
			{
				result.type = BitmapFilterType.INNER;
			}
			else if (filter.onTop)
			{
				result.type = BitmapFilterType.OUTER;
			}

			return result;
		}

		public static function blurFilterNativeToStructure(filter:flash.filters.BlurFilter):sweezy.swf.structure.BlurFilter
		{
			var result:sweezy.swf.structure.BlurFilter = new sweezy.swf.structure.BlurFilter();
			result.blurX = filter.blurX;
			result.blurY = filter.blurY;
			result.passes = filter.quality;

			return result;
		}

		public static function blurFilterStructureToNative(filter:sweezy.swf.structure.BlurFilter):flash.filters.BlurFilter
		{
			var result:flash.filters.BlurFilter = new flash.filters.BlurFilter();
			result.blurX = filter.blurX;
			result.blurY = filter.blurY;
			result.quality = filter.passes;

			return result;
		}

		public static function colorMatrixFilterNativeToStructure(filter:flash.filters.ColorMatrixFilter):sweezy.swf.structure.ColorMatrixFilter
		{
			var result:sweezy.swf.structure.ColorMatrixFilter = new sweezy.swf.structure.ColorMatrixFilter();
			result.matrix = filter.matrix.slice();

			return result;
		}

		public static function colorMatrixFilterStructureToNative(filter:sweezy.swf.structure.ColorMatrixFilter):flash.filters.ColorMatrixFilter
		{
			var result:flash.filters.ColorMatrixFilter = new flash.filters.ColorMatrixFilter();
			result.matrix = filter.matrix.slice();

			return result;
		}

		public static function convolutionFilterNativeToStructure(filter:flash.filters.ConvolutionFilter):sweezy.swf.structure.ConvolutionFilter
		{
			var result:sweezy.swf.structure.ConvolutionFilter = new sweezy.swf.structure.ConvolutionFilter();
			result.bias = filter.bias;
			result.clamp = filter.clamp;
			result.defaultColor = ColorConverter.colorAndAlphaToRgba(filter.color, filter.alpha);
			result.divisor = filter.divisor;
			result.matrix = filter.matrix.slice();
			result.matrixX = filter.matrixX;
			result.matrixY = filter.matrixY;
			result.preserveAlpha = filter.preserveAlpha;

			return result;
		}

		public static function convolutionFilterStructureToNative(filter:sweezy.swf.structure.ConvolutionFilter):flash.filters.ConvolutionFilter
		{
			var result:flash.filters.ConvolutionFilter = new flash.filters.ConvolutionFilter();
			result.alpha = filter.defaultColor.alpha / 255;
			result.bias = filter.bias;
			result.clamp = filter.clamp;
			result.color = ColorConverter.rgbToColor(filter.defaultColor);
			result.divisor = filter.divisor;
			result.matrix = filter.matrix.slice();
			result.matrixX = filter.matrixX;
			result.matrixY = filter.matrixY;
			result.preserveAlpha = filter.preserveAlpha;

			return result;
		}

		public static function dropShadowFilterNativeToStructure(filter:flash.filters.DropShadowFilter):sweezy.swf.structure.DropShadowFilter
		{
			var result:sweezy.swf.structure.DropShadowFilter = new sweezy.swf.structure.DropShadowFilter();
			result.angle = filter.angle;
			result.blurX = filter.blurX;
			result.blurY = filter.blurY;
			result.distance = filter.distance;
			result.dropShadowColor = ColorConverter.colorAndAlphaToRgba(filter.color, filter.alpha);
			result.innerShadow = filter.inner;
			result.knockout = filter.knockout;
			result.passes = filter.quality;
			result.strength = filter.strength;

			return result;
		}

		public static function dropShadowFilterStructureToNative(filter:sweezy.swf.structure.DropShadowFilter):flash.filters.DropShadowFilter
		{
			var result:flash.filters.DropShadowFilter = new flash.filters.DropShadowFilter();
			result.alpha = filter.dropShadowColor.alpha / 255;
			result.angle = filter.angle;
			result.blurX = filter.blurX;
			result.blurY = filter.blurY;
			result.color = ColorConverter.rgbToColor(filter.dropShadowColor);
			result.distance = filter.distance;
			result.inner = filter.innerShadow;
			result.knockout = filter.knockout;
			result.quality = filter.passes;
			result.strength = filter.strength;

			return result;
		}

		public static function glowFilterNativeToStructure(filter:flash.filters.GlowFilter):sweezy.swf.structure.GlowFilter
		{
			var result:sweezy.swf.structure.GlowFilter = new sweezy.swf.structure.GlowFilter();
			result.blurX = filter.blurX;
			result.blurY = filter.blurY;
			result.glowColor = ColorConverter.colorAndAlphaToRgba(filter.color, filter.alpha);
			result.innerGlow = filter.inner;
			result.knockout = filter.knockout;
			result.passes = filter.quality;
			result.strength = filter.strength;

			return result;
		}

		public static function glowFilterStructureToNative(filter:sweezy.swf.structure.GlowFilter):flash.filters.GlowFilter
		{
			var result:flash.filters.GlowFilter = new flash.filters.GlowFilter();
			result.alpha = filter.glowColor.alpha / 255;
			result.blurX = filter.blurX;
			result.blurY = filter.blurY;
			result.color = ColorConverter.rgbToColor(filter.glowColor);
			result.inner = filter.innerGlow;
			result.knockout = filter.knockout;
			result.quality = filter.passes;
			result.strength = filter.strength;

			return result;
		}

		public static function gradientBevelFilterNativeToStructure(filter:flash.filters.GradientBevelFilter):sweezy.swf.structure.GradientBevelFilter
		{
			var result:sweezy.swf.structure.GradientBevelFilter = new sweezy.swf.structure.GradientBevelFilter();
			result.angle = filter.angle;
			result.blurX = filter.blurX;
			result.blurY = filter.blurY;
			result.distance = filter.distance;
			result.innerShadow = filter.type === BitmapFilterType.FULL || filter.type === BitmapFilterType.INNER;
			result.knockout = filter.knockout;
			result.onTop = filter.type === BitmapFilterType.FULL || filter.type === BitmapFilterType.OUTER;
			result.passes = filter.quality;
			result.strength = filter.strength;
			result.gradientColors = [];
			result.gradientRatio = [];
			gradientNativeToStructure(filter.alphas, filter.colors, filter.ratios, result.gradientColors, result.gradientRatio);

			return result;
		}

		public static function gradientBevelFilterStructureToNative(filter:sweezy.swf.structure.GradientBevelFilter):flash.filters.GradientBevelFilter
		{
			var result:flash.filters.GradientBevelFilter = new flash.filters.GradientBevelFilter();
			result.angle = filter.angle;
			result.blurX = filter.blurX;
			result.blurY = filter.blurY;
			result.distance = filter.distance;
			result.knockout = filter.knockout;
			result.quality = filter.passes;
			result.strength = filter.strength;
			if (filter.innerShadow && filter.onTop)
			{
				result.type = BitmapFilterType.FULL;
			}
			else if (filter.innerShadow)
			{
				result.type = BitmapFilterType.INNER;
			}
			else if (filter.onTop)
			{
				result.type = BitmapFilterType.OUTER;
			}
			result.alphas = [];
			result.colors = [];
			result.ratios = [];
			gradientStructureToNative(filter.gradientColors, filter.gradientRatio, result.alphas, result.colors, result.ratios);

			return result;
		}

		public static function gradientGlowFilterNativeToStructure(filter:flash.filters.GradientGlowFilter):sweezy.swf.structure.GradientGlowFilter
		{
			var result:sweezy.swf.structure.GradientGlowFilter = new sweezy.swf.structure.GradientGlowFilter();
			result.blurX = filter.blurX;
			result.blurY = filter.blurY;
			result.innerShadow = filter.type === BitmapFilterType.FULL || filter.type === BitmapFilterType.INNER;
			result.knockout = filter.knockout;
			result.onTop = filter.type === BitmapFilterType.FULL || filter.type === BitmapFilterType.OUTER;
			result.passes = filter.quality;
			result.strength = filter.strength;
			result.gradientColors = [];
			result.gradientRatio = [];
			gradientNativeToStructure(filter.alphas, filter.colors, filter.ratios, result.gradientColors, result.gradientRatio);

			return result;
		}

		public static function gradientGlowFilterStructureToNative(filter:sweezy.swf.structure.GradientGlowFilter):flash.filters.GradientGlowFilter
		{
			var result:flash.filters.GradientGlowFilter = new flash.filters.GradientGlowFilter();
			result.blurX = filter.blurX;
			result.blurY = filter.blurY;
			result.knockout = filter.knockout;
			result.quality = filter.passes;
			result.strength = filter.strength;
			if (filter.innerShadow && filter.onTop)
			{
				result.type = BitmapFilterType.FULL;
			}
			else if (filter.innerShadow)
			{
				result.type = BitmapFilterType.INNER;
			}
			else if (filter.onTop)
			{
				result.type = BitmapFilterType.OUTER;
			}
			result.alphas = [];
			result.colors = [];
			result.ratios = [];
			gradientStructureToNative(filter.gradientColors, filter.gradientRatio, result.alphas, result.colors, result.ratios);

			return result;
		}

		private static function gradientNativeToStructure(alphas:Array, colors:Array, ratios:Array, gradientColors:Array, gradientRatios:Array):void
		{
			for (var i:uint, len:uint = alphas.length; i < len; i++)
			{
				gradientRatios[i] = ratios[i];
				gradientColors[i] = ColorConverter.colorAndAlphaToRgba(colors[i], alphas[i]);
			}
		}

		private static function gradientStructureToNative(gradientColors:Array, gradientRatios:Array, alphas:Array, colors:Array, ratios:Array):void
		{
			for (var i:uint, len:uint = gradientColors.length; i < len; i++)
			{
				ratios[i] = gradientRatios[i];
				var rgba:RGBA = gradientColors[i] as RGBA;
				alphas[i] = rgba.alpha / 255;
				colors[i] = ColorConverter.rgbToColor(rgba);
			}
		}
	}
}
